﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BigLotterySyndicate.Classes;
using SyndicateDAO.DatabaseObject;
using System.Text;
using System.Text.RegularExpressions;
using SyndicateBusiness.Classes;

namespace BigLotterySyndicate.MyAccount
{
    public partial class DownloadXML : BasePublicPage
    {
        public string TokenValue
        {
            get
            {
                if (Page.Request["t"] != null)
                    return Page.Request["t"].ToString();
                else
                    return null;
            }
        }

        public bool DownloadAttachement
        {
            get
            {
                if (Page.Request["a"] != null)
                    return true;
                else
                    return false;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (TokenValue != null)
            {
                user u = this.BusinessFacade.UserBL.GetSingleUserByToken(TokenValue,this.BusinessFacade.CurrentSyndicate.id);
                if (u != null)
                {
                    string document = GenerateXML(u);

                    Response.ContentType = "text/xml";
                    if (DownloadAttachement)
                        Response.AppendHeader("content-disposition", "attachment; filename=draws.xml");

                    Response.Write(document);
                    Response.End();
                }
                else
                    GenerateError();
            }
            else
            {
                GenerateError();
            }
          

        }

        private void GenerateError()
        {
            Response.ContentType = "text/xml";

            Response.Write("<?xml version='1.0' encoding='utf-8' ?>\n\r");
            Response.Write("<error msg='Invalid access token.' />");
            Response.End();
        }

        private string GenerateXML(user user)
        {
            SyndicateDAO.DatabaseObject.DataContext dc = new DataContext();

            var draws = this.BusinessFacade.DrawBL.GetAllBySyndicateId(dc,user.syndicateId);

            var users = this.BusinessFacade.UserBL.GetAllBySyndicateId(dc,user.syndicateId);

            var players = this.BusinessFacade.PlayerBL.GetAll(dc);
            if (Utilities.isMobileApplication())
            {
                this.BusinessFacade.EventLogBL.InsertEntry(user, "User [" + user.id.ToString() + "] downloaded xml from a mobile application. [" + HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"].ToString() + "]", eventLog.eventType.VIEW);
            }
            else if (Utilities.isMobileBrowser())
            {
                this.BusinessFacade.EventLogBL.InsertEntry(user, "User [" + user.id.ToString() + "] downloaded xml from a mobile browser. [" + HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"].ToString() + "]", eventLog.eventType.VIEW);
            }
            else
            {
                this.BusinessFacade.EventLogBL.InsertEntry(user, "User [" + user.id.ToString() + "] downloaded xml from web. [" + HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"].ToString() + "]", eventLog.eventType.VIEW);
            }
           /// this.BusinessFacade.EventLogBL.InsertEntry(user, logDesc, eventLog.eventType.VIEW);
            //this.BusinessFacade.EventLogBL.InsertEntry(user, HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"].ToString(), eventLog.eventType.VIEW);
            var query = from d in draws
                        join p in players on d equals p.draw
                        join u in users on p.user equals u
                        where u.email == user.email
                        select new {D=d, Lines = d.lines};

            StringBuilder builder = new StringBuilder();
            builder.AppendFormat("<?xml version='1.0' encoding='utf-8' ?>\n\r");

            


            if (query.Count() > 0)
            {
                var userDrawsCount = query.Select(d => d.D).Where(d => d.status == draw.drawstatus.OPEN).Count();

                string desc = String.Empty;
                string status = CalculateUserStatus(user, userDrawsCount,out desc);
                builder.AppendFormat("<draws amount='{0}' accountstatus='{1}' desc='{2}' updated='{3}' >\n\r", String.Format("{0:0.00}", user.funds), status, desc, this.BusinessFacade.EventLogBL.GetLastEntry(user.syndicateId).dateCreated.ToString("dd-MM-yyyy HH:mm:ss"));
                int order = 1;
                foreach (var item in query.OrderByDescending(i=>i.D.drawdate))
                {
                    builder.AppendFormat("\t<draw id='{3}' order='{5}' date='{0}' status='{1}' type='{4}' result='{2}'>\n\r", item.D.drawdate.ToString("dd MMM yyyy"), item.D.status, this.BusinessFacade.DrawBL.GetResult(item.D.id) != null ? this.BusinessFacade.DrawBL.GetResult(item.D.id).numbers : "", item.D.id, item.D.type, order);
                    builder.AppendFormat("{0}", GenerateLines(item.Lines.AsQueryable()));
                    builder.AppendFormat("\t</draw>\n\r");
                    order++;
                }
                builder.AppendFormat("</draws>");

            }
            else
                builder.AppendFormat("<draws amount='{0}' />\n\r", String.Format("{0:0.00}", user.funds));

            return builder.ToString();
        }

        public string GenerateLines(IQueryable<line> lines)
        {
            StringBuilder builder = new StringBuilder();

            if (lines.Count() > 0)
            {
                builder.Append("\t\t<lines>\n\r\r");

                foreach (line item in lines)
                {
                    builder.AppendFormat("\t\t\t<line numbers='{0}' raffle='{1}' />\n\r", item.numbers, item.raffle != null ? item.raffle : "");
                  
                }

                builder.Append("\t\t</lines>\n\r");
            }
            else
                builder.Append("\t\t<lines />\n\r");

            return builder.ToString();
        }


        public string CalculateUserStatus(user user, int userDrawsCount,out string desc)
        {
            desc = String.Empty;

            var allOpenCount = this.BusinessFacade.DrawBL.GetAllBySyndicateId(user.syndicateId).Where(d=>d.status == draw.drawstatus.OPEN).Count();

            //var userDrawsCount = query.Select(d => d.D).Where(d => d.status == draw.drawstatus.OPEN).Count();

            if (user.funds > 0)
            {
                if (userDrawsCount >= allOpenCount)
                {
                    desc = "Status: GREEN - user has funds and is added to all open draws. Action: None.";
                    return "1"; // all ok
                }
                else
                {
                    desc = "Status: ORANGE - user has funds but is not added to some of the open draws. Action: Contact syndicate manager.";
                    return "2"; // warning - there are opend draws, user have funds but is not added
                }
            }
            else
            {
                if (userDrawsCount >= allOpenCount)
                {
                    desc ="Status: PURPLE - user has no funds but there are no open draws to be added to at the moment. Action: None.";
                    return "3"; // warning - user has no funds, but no worries, there are no open draws
                }
                else
                {
                    desc = "Status: RED - there are open draws but user has no funds and cannot be added to that draws. Action: Add more funds.";
                    return "4"; // bad - there are opend draws, user have no funds and cannot be added
                }
            }
        
        }


        internal class DrawXML
        {
            public draw D
            { get; set; }
            public IQueryable<line> Lines
            { get; set; }

            public DrawXML()
            { }

            public DrawXML(draw _d, IQueryable<line> _l)
            {
                this.D = _d;
                this.Lines = _l;
            }
        }


            IQueryable<line> GetLines(int drawId)
            {
                return this.BusinessFacade.LineBL.SelectAllByDrawId(drawId);
            }
    }
}